package MyFramePro.Service.Impl;

import MyFramePro.Constants.SystemConstants;
import MyFramePro.Domain.Entity.Article;
import MyFramePro.Domain.Entity.Comment;
import MyFramePro.Domain.Entity.User;
import MyFramePro.Domain.ResponseResult;
import MyFramePro.Domain.Vo.CommentVo;
import MyFramePro.Domain.Vo.PageVo;
import MyFramePro.Enums.AppHttpCodeEnum;
import MyFramePro.Exception.SystemException;
import MyFramePro.Mapper.CommentMapper;
import MyFramePro.Service.CommentService;
import MyFramePro.Utils.BeanCopyUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 评论表(Comment)表服务实现类
 *
 * @author makejava
 * @since 2023-05-01 19:30:00
 */
@Service("commentService")
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private CommentServiceImpl commentService;

    @Resource
    private UserServiceImpl userService;

    /**
     * 这里是查询评论的功能
     */
    @Override
    public ResponseResult commentList(String commentType,Long articleId, Integer pageNum, Integer pageSize) {

        //1. 查询对应文章的根评论
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        if(!Objects.isNull(articleId)) {    //判断传入的文章 ID 是否为空
            //1.1 查询对应文章的 ID
            queryWrapper.eq(Comment::getArticleId, articleId);
        }
        //1.2 查询根评论
        queryWrapper.eq(Comment::getRootId, SystemConstants.COMMENT_ROOT_ID);
        ///1.3 查询评论的类型
        queryWrapper.eq(Comment::getType,commentType);

        //2.分页查询
        Page<Comment> commentPage = new Page<>(pageNum,pageSize);
        commentService.page(commentPage,queryWrapper);

        //3.由于前端需求的字段格式不能够直接满足，所以这里使用 Vo 类型来进行转换
        long total = commentPage.getTotal();    //获取到查询的数量

        List<CommentVo> commentVos = getCommentVos(commentPage.getRecords());   //一转 (rows中的字段)

        //4.查询所有根评论对应的子评论集合，并且赋值给对应的属性

//        commentVos.forEach(   //forEach 的方式
//                commentVo -> commentVo.setChildren(
//                        getChildren(commentVo.getId())
//                )
//        );

        List<CommentVo> children=null;

        for (CommentVo commentVo:commentVos){   //遍历根评论
            //4.1 查询对应的子评论
            if(!Objects.isNull(commentVo.getId())) {
                children = getChildren(commentVo.getId());
            }
            //4.2 进行子评论赋值
            commentVo.setChildren(children);
        }

        PageVo pageVo = new PageVo(commentVos,total);   //二转 (rows + total 字段)

        return ResponseResult.okResult(pageVo);
    }


    /**
     * 这里是发表评论的功能
     */
    @Override
    public ResponseResult sendComment(Comment comment) {

        if(!StringUtils.hasText(comment.getContent())){  //评论内容为空的话，则发表评论失败
            throw new SystemException(AppHttpCodeEnum.COMMENT_NOT_NULL);
        }

        commentService.save(comment);

        return ResponseResult.okResult();
    }



    /********************************************************************************************************【下面是封装的方法】
    /**
     * 这里为查询评论中的 toCommentUserName 和 username，以封装 Vo 对象
     */
    private List<CommentVo> getCommentVos(List<Comment> commentList) {
        List<CommentVo> commentVos = BeanCopyUtils.myCopyBeanList(commentList, CommentVo.class);

        for(CommentVo commentVo:commentVos) {
            //1.通过 createBy 查询对应的用户昵称 username，即 nickName
            User user = userService.getById(commentVo.getCreateBy());
            if(!Objects.isNull(user)) {
                String nickName = user.getNickName();
                if (!Objects.isNull(nickName)) {
                    commentVo.setUsername(nickName);
                }
            }


            //2.通过 toCommentUserId 查询对应的用户昵称 toCommentUserName
            //2.1 判断 toCommentUserId 是否为 -1，为-1 则不进行查询 (因为 -1 为根评论，不代表回复任何用户的评论)
            if(commentVo.getToCommentUserId()!=-1){
                User user1 = userService.getById(commentVo.getToCommentUserId());
                if(!Objects.isNull(user1)) {
                    String commentUserName = user1.getNickName();
                    commentVo.setToCommentUserName(commentUserName);
                }
            }
        }
        return commentVos;
    }


    /**
     * 根据根评论的 ID 查询对应的子评论的集合
     */
    private List<CommentVo> getChildren(Long id) {

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getRootId,id);  //子评论的 rootId 与对应的 Id 相关联，即与相应的根评论对应
        queryWrapper.orderByAsc(Comment::getCreateTime);

        List<Comment> comments = commentService.list(queryWrapper); //得到子评论
        List<CommentVo> commentVos = getCommentVos(comments);   //将 children 转换为 Vo 对象类型

        return commentVos;
    }

}

